﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Unity.Configuration;
using SmartMotion.Core.Reflection;
using Sunny.UI;
using Unity;

namespace SmartMotion.Core
{
    public class UnityIoc
    {
        #region 属性单例模式

        private static readonly Lazy<UnityIoc> Instance = new Lazy<UnityIoc>(() => new UnityIoc());

        private UnityIoc()
        {
            try
            {
                ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
                string strParamFilePath = Path.Combine(Environment.CurrentDirectory + "\\Unity.Config");
                fileMap.ExeConfigFilename = strParamFilePath;//找配置文件的路径
                Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
                UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
                Container = new UnityContainer();
                section.Configure(Container, "UnityContainer");
            }
            catch (Exception e)
            {
                UIMessageBox.ShowError($"Unity配置文件有错误,请检查\r\n {e.Message} \r\n {e.StackTrace}");
            }
        }
        public static UnityIoc Ins { get; } = Instance.Value;

        public IUnityContainer Container;

        #endregion

        public void RegisterType<T>()
        {
            Container.RegisterType<T>();
        }
        public  void RegisterSingleton<T>()
        {
            Container.RegisterSingleton<T>();
        }
        public T Resolve<T>(string typeName)
        {
            try
            {
                T myT = Container.Resolve<T>(typeName);
                return myT;
            }
            catch (Exception e)
            {
              
                UIMessageBox.ShowError($"Unity配置文件有错误,请检查{typeName} \r\n {e.Message} \r\n {e.StackTrace}");

                return default(T);
            }
        }

        public T Resolve<T>()
        {
            try
            {
                T myT = Container.Resolve<T>();
                return myT;
            }
            catch (Exception e)
            {
               
                UIMessageBox.ShowError($"Unity配置文件有错误,请检查{typeof(T).Name} \r\n {e.Message} \r\n {e.StackTrace}");

                return default(T);
            }
        }

        public List<DllTypeInfo> LoadDllFromDirectory<T>()
        {
            List<DllTypeInfo> deviceInfos = new List<DllTypeInfo>();
            string pathFull = $"{Environment.CurrentDirectory}";
            DirectoryInfo folder = new DirectoryInfo(pathFull);
            var files = folder.GetFiles("*.dll");

            foreach (var file in files)//遍历每一个DLL
            {
                try
                {
                    var types = Assembly.LoadFile(file.FullName).GetTypes();
                    foreach (var item in types)//遍历DLL里每一个类型
                    {
                        if (typeof(T).IsAssignableFrom(item))
                        {

                            if (item.FullName != typeof(T).FullName)//不要基类
                            {
                                if (!item.IsAbstract)//不要抽象类
                                {
                                    deviceInfos.Add(new DllTypeInfo() { Dll = file.FullName, TypeName = item.FullName });
                                }

                            }
                        }
                    }
                }
                catch (Exception err)
                {
                    continue;
                }
            }

            return deviceInfos;
        }

    }
}
